﻿namespace CivilisationLib
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;

    [Serializable] public class Ville : IVille
    {
        /// <summary>
        /// ordre d'ajout des cases à exploiter
        /// </summary>
        private static readonly int[,] ORDRE = { { 0, 0 }, { 0, 1 }, { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 2 }, { -1, 1 }, { 1, 1 }, { -2, 0 }, { 2, 0 }, { -1, -1 }, { 1, -1 }, { 0, -2 }, { 0, 3 }, { -1, 2 }, { 1, 2 }, { -2, 1 }, { 2, 1 }, { -3, 0 }, { 3, 0 }, { -2, -1 }, { 2, -1 }, { -1, -2 }, { 1, -2 }, { 0, -3 } };
        /// <summary>
        /// nombre maximal de case exploitée par la ville
        /// </summary>
        private static readonly int EXPMAX = 25;

        private int _minerai;
        private int _nourriture;
        private int _nbRes;
        private int _population;
        private Unite _enProduction;
        private List<Position> _exploitations;
        
        private int _nbExpVirtuel;
        private Position _pos;
        private Civilisation _civilisation;

        public int minerai { get { return _minerai; } set { _minerai = value; } }
        public int nourriture { get { return _nourriture; } set { _nourriture = value; } }
        public int nbRes { get { return _nbRes; } set { _nbRes = value; } }
        public int population { get { return _population; } set { _population = value; } }
        public Unite enProduction { get { return _enProduction; } set { _enProduction = value; } }
        public List<Position> exploitations { get { return _exploitations; } set { _exploitations = value; } }
        public Position pos { get { return _pos; } set { _pos = value; } }
        public Civilisation civilisation { get { return _civilisation; } set { _civilisation = value; } }
        public int nbExpVirtuel { get { return _nbExpVirtuel; } set { _nbExpVirtuel = value; } }

        ~Ville()
        {
        }

        public Ville(Position p, Civilisation civ)
        {
            nbRes = 10;
            minerai = 0;
            nourriture = 0;
            population = 1;
            pos = p;
            exploitations = new List<Position>();
            nbExpVirtuel = 1;
            civilisation = civ;
            exploitations.Add(pos);
            civilisation.joueur.partie.carte.setVille(p, this);
            enProduction = civ.fabriqueCivilisation.produireEtudiant(p, civ);
        }

        /// <summary>
        /// la ville est conquite par la civilisation
        /// </summary>
        /// <param name="civ"> la civilisation conquérant la ville </param>
        public void conquerir(Civilisation civ)
        {
            civilisation = civ;
        }

        /// <summary>
        /// exécute les actions de récolter, produire et croitre
        /// </summary>
        public void actions()
        {
            recolter();
            produire();
            croitre();
        }

        /// <summary>
        /// produit une unité si la ville a assez de minerai
        /// </summary>
        public void produire()
        {
            if (minerai >= enProduction.cout)
            {
                civilisation.fabriqueCivilisation.creerUnite(enProduction);
                modifierProduction(enProduction.nom);
            }
        }

        /// <summary>
        /// modifie l'unité produite dans la ville
        /// le minerai de la ville passe à 0
        /// </summary>
        /// <param name="s"></param>
        public void modifierProduction(string s)
        {
            switch (s)
            {
                case "Etudiant":
                    enProduction = civilisation.fabriqueCivilisation.produireEtudiant(pos, civilisation);
                    minerai = 0;
                    break;
                case "Enseignant":
                    enProduction = civilisation.fabriqueCivilisation.produireEnseignant(pos, civilisation);
                    minerai = 0;
                    break;
                case "Directeur":
                    enProduction = civilisation.fabriqueCivilisation.produireDirecteur(pos, civilisation);
                    minerai = 0;
                    break;
            }
        }

        /// <summary>
        /// croit si la ville a assez de nourriture
        /// </summary>
        public void croitre()
        {
            if (nourriture >= nbRes)
            {
                population++;
                nourriture = 0;
                nbRes += nbRes / 2;
                exploiter();
            }
        }

        /// <summary>
        /// ajoute une case aux cases exploitées si possible
        /// </summary>
        public void exploiter()
        {
            if (nbExpVirtuel<EXPMAX)
            {
                if (pos.X + ORDRE[nbExpVirtuel, 0] < civilisation.joueur.partie.carte.largeur && pos.Y + ORDRE[nbExpVirtuel, 1] < civilisation.joueur.partie.carte.largeur && pos.X + ORDRE[nbExpVirtuel, 0] >= 0 && pos.Y + ORDRE[nbExpVirtuel, 1] >= 0)
                {
                    exploitations.Add(new Position(pos.X + ORDRE[nbExpVirtuel, 0], pos.Y + ORDRE[nbExpVirtuel, 1]));
                    nbExpVirtuel++;
                }
                else
                {
                    nbExpVirtuel++;
                    exploiter();
                }
            }
        }

        /// <summary>
        /// récolte les ressources de chaque case exploitée
        /// </summary>
        public void recolter()
        {
            foreach (Position p in exploitations)
            {
                if(!(enProduction is Enseignant)) nourriture += civilisation.joueur.partie.carte.getCase(p.X, p.Y).nourriture;
                minerai += civilisation.joueur.partie.carte.getCase(p.X, p.Y).minerai;
            }
        }

    }

}